package com.lovezy.platform.member.service.impl;

import com.google.common.collect.ImmutableMap;
import com.lovezy.platform.core.jwt.JwtUtil;
import com.lovezy.platform.core.valid.ValidatorUtil;
import com.lovezy.platform.member.enums.EmailStatusEnum;
import com.lovezy.platform.member.enums.MemberRoleEnum;
import com.lovezy.platform.member.form.RegisterForm;
import com.lovezy.platform.member.form.ShopRegisterForm;
import com.lovezy.platform.member.model.Member;
import com.lovezy.platform.member.service.MemberService;
import com.lovezy.platform.member.service.RegistrationService;
import com.lovezy.platform.member.vo.MemberVo;
import com.lovezy.platform.member.vo.ShopMemberVo;
import com.lovezy.platform.message.email.enums.EmailIllegalEnum;
import com.lovezy.platform.message.email.enums.EmailTypeEnum;
import com.lovezy.platform.message.email.exception.IllegalEmailException;
import com.lovezy.platform.message.email.service.EmailService;
import com.lovezy.platform.message.email.service.EmailServiceTarget;
import com.lovezy.platform.message.email.service.VerifyEmailResult;
import com.lovezy.platform.shop.service.ShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import static com.lovezy.platform.core.utils.ObjectUtil.copy;
import static com.lovezy.platform.core.utils.ObjectUtil.copyTo;

/**
 * 注册服务实现
 * Created by jin on 2017/11/9.
 */
@Service("emailRegistrationService")
public class EmailRegistrationServiceImpl implements RegistrationService{
    @Autowired
    private EmailService emailService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private ShopService shopService;

    @Value("${app.register.email.auth}")
    private String authUrl;

    @Override
    public void sendAuthKey(@com.lovezy.platform.core.valid.annotation.Email(errorMsg = "邮件格式错误") String address) {
        ValidatorUtil.validate(address,com.lovezy.platform.core.valid.annotation.Email.class);
        EmailServiceTarget target = new EmailServiceTarget();
        target.setEmailType(EmailTypeEnum.MEMBER_REGISTER);
        target.setAddress(address);
        target.setSubject("注册用户");
        String authKey = target.createAuthKey();
        String text = "验证你的账户" + authUrl + authKey;
        target.setText(text);
        emailService.sendEmail(target);
    }

    @Transactional
    @Override
    public MemberVo regMember(RegisterForm form) {
        Member m = copyTo(form, new Member());
        emailService.verifyEmail(form.getAuthKey(), EmailTypeEnum.MEMBER_REGISTER, result -> resultHandler(result, m));
        return createTokenForNewRegMember(m);
    }

    private boolean resultHandler(VerifyEmailResult result,Member m) {
        if (result.isSuccess()) {
            m.setEmail(result.getEmail().getEmail());
            m.setEmailStatus(EmailStatusEnum.AUTHENTICATED.value());
            memberService.addMember(m);
            return true;
        }else{
            EmailIllegalEnum illegal = result.getIllegal();
            throw new IllegalEmailException(illegal);
        }
    }

    @Override
    @Transactional
    public ShopMemberVo regShopMember(ShopRegisterForm form) {
        Member m = new Member();
        ValidatorUtil.validateAndCopy(form,m);
        m.setRole(MemberRoleEnum.BUSINESS.value());
        if (StringUtils.hasText(form.getEmail())) {
            m.setEmailStatus(EmailStatusEnum.AUTHENTICATED.value());
        }
        m.setNickname(m.getUsername());
        Member newMember = memberService.addMember(m);
        shopService.addShop(newMember, form);
        MemberVo memberVo =  createTokenForNewRegMember(newMember);
        return new ShopMemberVo(memberVo, form.getAddress(), form.getTel());
    }

    private MemberVo createTokenForNewRegMember(Member member) {
        String jwt = JwtUtil.createJavaWebToken(ImmutableMap.of("mid", member.getMemberId()));
        MemberVo memberVo = new MemberVo();
        copy(member, memberVo);
        memberVo.setToken(jwt);
        return memberVo;
    }

}
